﻿#region Using namespaces

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using BOL.IO;

#endregion

namespace BOL.Apps.GeneNetworkBrowser.IO
{
    public class ProbesetValueReader : IReader<Dictionary<string,double[]>>
    {
        #region Private variables

        //private bool _isFirstRowHeader;
        private string[] _header;
        private double[] _os;
        private int[] _status;
        private int _numberOfValues;
        private char[] _delimiters;
        private StreamReader _sr;

        #endregion

        #region Public properties

        public string[] Header { get { return _header; } }
        public double[] OS { get { return _os; } }
        public int[] Status { get { return _status; } }
        
        #endregion

        #region Constructors

        public ProbesetValueReader(string path, char[] delimiters)
        {
            _sr = new StreamReader(new FileStream(path, FileMode.Open));
            _delimiters = delimiters;
        }

        #endregion

        #region Public methods

        public Dictionary<string, double[]> Read()
        {
            string line = String.Empty;
            string[] temp; // temporary string array splitted by delimiter

            string probesetId;
            double[] values;
            var probesetValues = new Dictionary<string, double[]>();

            while (!_sr.EndOfStream)
            {
                line = _sr.ReadLine();
                temp = line.Split(_delimiters);
                values = new double[_numberOfValues];
                probesetId = temp[0];

                if (probesetId == "ID")
                {
                    _numberOfValues = temp.Length - 1;
                    _header = new string[_numberOfValues];
                    for (int i = 0; i < _numberOfValues; i++)
                        _header[i] = temp[i + 1];
                }
                else if (probesetId == "OS")
                {
                    _os = new double[_numberOfValues];
                    for (int i = 0; i < _numberOfValues; i++)
                        Double.TryParse(temp[i + 1], out _os[i]);
                }
                else if (probesetId == "Status")
                {
                    _status = new int[_numberOfValues];
                    for (int i = 0; i < _numberOfValues; i++)
                        Int32.TryParse(temp[i + 1], out _status[i]);
                }
                else
                {
                    for (int i = 0; i < _numberOfValues; i++)
                       Double.TryParse(temp[i + 1], out values[i]);
                    //var newValues = ZTransform(values);
                    //probesetValues.Add(probesetId, newValues);
                    probesetValues.Add(probesetId, values);
                }
            }

            return probesetValues;
        }

        private double[] ZTransform(double[] values)
        {
            double mean, variance, stdDev, diff;

            int length = values.Length;
            if (length < 1)
                throw new ArgumentException();
            double[] newValues = new double[length];

            mean = values.Average();
            variance = 0;

            for (int i = 0; i < length; i++)
            {
                diff = values[i] - mean;
                variance += diff * diff;
            }
            variance /= (double)(length - 1);
            stdDev = Math.Sqrt(variance);

            for (int j = 0; j < length; j++)
                newValues[j] = (values[j] - mean) / stdDev;

            return newValues;
        }

        public void Close()
        {
            _sr.Close();
        }

        #endregion
    }
}
